package com.smartcommunity.service.village.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.smartcommunity.dao.access.AccessDeviceDao;
import com.smartcommunity.dao.villageGroup.VillageGroupDao;
import com.smartcommunity.entity.ac.AccessDevice;
import com.smartcommunity.entity.statistic.StatisticsVillageDataResp;
import com.smartcommunity.entity.villagegroup.GroupDevice;
import com.smartcommunity.entity.villagegroup.VillageGroup;
import com.smartcommunity.redis.RedisUtil;
import com.smartcommunity.api.user.UserApi;
import com.smartcommunity.base.bean.ExceptionCode;
import com.smartcommunity.base.common.CacheMap;
import com.smartcommunity.bean.constant.Constant;
import com.smartcommunity.bean.entity.*;
import com.smartcommunity.bean.enumeration.ResultCode;
import com.smartcommunity.bean.model.Pager;
import com.smartcommunity.bean.model.Result;
import com.smartcommunity.dao.camera.CameraDao;
import com.smartcommunity.dao.common.SystemDao;
import com.smartcommunity.dao.device.DeviceDao;
import com.smartcommunity.dao.people.PeopleDao;
import com.smartcommunity.dao.sixEntity.SixEntityDao;
import com.smartcommunity.dao.village.*;
import com.smartcommunity.entity.Unit.Unit;
import com.smartcommunity.entity.Unit.UnitSearch;
import com.smartcommunity.entity.device.FireDevice;
import com.smartcommunity.entity.people.People;
import com.smartcommunity.entity.system.SysParams;
import com.smartcommunity.entity.village.*;
import com.smartcommunity.entity.village.dto.VillageForPeopleManage;
import com.smartcommunity.exception.BusinessException;
import com.smartcommunity.service.people.PeopleService;
import com.smartcommunity.service.tag.TagService;
import com.smartcommunity.service.village.VillageService;
import com.smartcommunity.utils.ArrayUtils;
import com.smartcommunity.utils.ToolDateTime;
import com.smartcommunity.utils.ToolPinyin;
import com.smartcommunity.utils.ToolString;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @version V2.0.1
 * @ClassName: VillageServiceImpl
 * @Description: 小区相关service
 */
@Service
@Slf4j
public class VillageServiceImpl implements VillageService {
    @Autowired
    private VillageDao villageDao;

    @Autowired
    private HttpSession httpSession;

    @Autowired
    private PeopleDao peopleDao;

    @Autowired
    private DeviceDao deviceDao;

    @Autowired
    private SixEntityDao sixEntityDao;

    @Autowired
    private UserApi userApi;

    @Autowired
    TagService tagService;

    @Autowired
    private SystemDao systemDao;

    @Autowired
    private SysVillageMapper sysVillageMapper;

    @Autowired
    private CameraDao cameraDao;

    @Autowired
    private HouseDao houseDao;

    @Autowired
    private RealCompanyDao realCompanyDao;

    @Autowired
    private RealPowerOrgDao realPowerOrgDao;

    @Autowired
    private RedisUtil redissonClient;

    @Autowired
    private VillageGroupDao villageGroupDao;

    @Autowired
    private AccessDeviceDao accessDeviceDao;

    @Autowired
    private PeopleService peopleService;

    @Value("${license.center.port:8888}")
    private String secret;

    /**
     * @Description: 获取房屋列表
     * @param: [house]
     * @return: com.smartcommunity.base.bean.Pager<com.smartcommunity.entity.face.House>
     */
    @Override
    public Pager<House> pageHousesByBuilding (House house) {
        int pageNumber = house.getPageNumber();
        int pageSize = house.getPageSize();
        List<House> houseList = villageDao.listHousesByBuilding2(house, (pageNumber-1)*pageSize, pageSize);
        int count = villageDao.countHousesByBuilding(house);
        Pager<House> realCompanyPeoplePager = new Pager<>(pageNumber, pageSize, count);
        realCompanyPeoplePager.setList(houseList);
        return realCompanyPeoplePager;
    }

    /**
     * @Description: 查询房间信息
     * @param: [map, pageNumber, pageSize]
     * @return: com.smartcommunity.base.bean.Pager<com.smartcommunity.entity.face.House>
     * @author: minsheng
     * @date: 2019/1/8 15:56
     */
    @Override
    public Pager<House> pageHouseNos (Map<String, String> map, int pageNumber, int pageSize) {
            PageHelper.startPage(pageNumber, pageSize);
            List<House> houseList = villageDao.listHouseNos(map);
            int totalNum = (int) ((Page) houseList).getTotal();
            Pager<House> realCompanyPeoplePager = new Pager<>(pageNumber, pageSize, totalNum);
            PageHelper.startPage(pageNumber, pageSize);
            realCompanyPeoplePager.setList(houseList);
            return realCompanyPeoplePager;
    }

    /**
     * @Description: 查询楼栋
     * @param: [map, pageNumber, pageSize]
     * @return: com.smartcommunity.base.bean.Pager<com.smartcommunity.entity.face.House>
     * @author: minsheng
     * @date: 2019/1/8 15:57
     */
    @Override
    public Pager<House> pageBuildingNos (Map<String, String> map, int pageNumber, int pageSize) {
        PageHelper.startPage(pageNumber, pageSize);
        List<House> houseList = villageDao.listBuildingNos(map);
        int totalNum = (int) ((Page) houseList).getTotal();
        Pager<House> pager = new Pager<>(pageNumber, pageSize, totalNum);
        PageHelper.startPage(pageNumber, pageSize);
        pager.setList(houseList);
        return pager;

    }

    /**
     * @Description: 查询楼栋集合
     * @param: [build]
     * @return: com.smartcommunity.base.bean.Pager<com.smartcommunity.entity.face.Building>
     * @author: zdy
     * @date: 2020/1/9
     */
    @Override
    public Pager<Building> pageBuildings (Building build) {
        int pageNumber = build.getPageNumber();
        int pageSize = build.getPageSize();
        PageHelper.startPage(pageNumber, pageSize);
        List<Building> list = villageDao.listBuildings(build);
        int count = (int) ((Page) list).getTotal();
        Pager<Building> pager = new Pager<>(pageNumber, pageSize, count);
        pager.setList(list);
        return pager;
    }

    /**
     * @Description: 查询楼栋的房间信息
     * @param: [House]
     * @return: java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
     * @author: zdy
     * @date: 2020/1/9
     */
    @Override
    public List<Map<String, Object>> listHousesByBuilding (House ho) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        List<House> houses = villageDao.listHousesByBuilding(ho);
        List<House> houseList = new ArrayList<>();
        List<String> floorNameList = new ArrayList<>();
        Map<String, Object> map1 = new HashMap<>(3);
        map1.put("villageCode", ho.getVillageCode());
        map1.put("houseNos", houses);
        map1.put("buildingNo", ho.getBuildingNo());
        // 添加人员标签
        List<People> peopleList = peopleDao.getPeoplesLabelByBuildingNo(map1);
        List<FireDevice> fireDeviceList = deviceDao.getFireDeviceAllHouse(map1);
        for (House house : houses) {
            // 记录楼层号
            if (!StringUtils.isEmpty(house.getFloor())) {
                if (!floorNameList.contains(house.getFloor())) {
                    floorNameList.add(house.getFloor());
                }
            }

            StringBuffer label = new StringBuffer();
            for (People people : peopleList) {
                if (people.getLabel() != null && house.getHouseNo().equals(people.getHouseNo())
                        && !StringUtils.contains(label.toString(), people.getLabel())) {
                    label.append(people.getLabel() + ",");
                }
            }
            // 添加烟感标签
            if (fireDeviceList != null && fireDeviceList.size() > 0) {
                for (FireDevice fireDevice : fireDeviceList) {
                    if (fireDevice.getHouseNo() != null && fireDevice.getHouseNo().equals(house.getHouseNo())
                            && !StringUtils.contains(label.toString(), "烟感")) {
                        label.append("烟感" + ",");
                    }
                }
            }
            if (label.length() > 0) {
                house.setLabel(label.substring(0, label.length() - 1));
            }
            houseList.add(house);
        }
        // 按照楼层将房屋分类
        Map<String, Object> map2;
        for (String floorName : floorNameList) {
            map2 = new HashedMap();
            List<House> houses1 = new ArrayList<>();
            for (House house : houseList) {
                if (floorName.equals(house.getFloor())) {
                    houses1.add(house);
                }
            }
            map2.put("floorName", floorName);
            map2.put("list", houses1);
            mapList.add(map2);
        }
        return mapList;
    }



    /**
     * @Description:
     * @param: [map]
     * @return: java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
     * @auther: minsheng
     * @date: 2019/1/25 16:07
     */
    @Override
    public List<Map<String, Object>> listHouses (Map<String, String> map) {
        return villageDao.listHouses(map);
    }

    /**
     * @Description: 查询权限小区的出入口数据
     * @param: [map]
     * @return: java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
     * @author: minsheng
     * @date: 2019/1/9 14:03
     */
    @Override
    public List<Map<String, Object>> listVillageEntranceExits (Map<String, String> map) {
        List<Map<String, Object>> list = new ArrayList<>();
        List<VillageEntranceExit> resultList;
        resultList = villageDao.listVillageEntranceExits(map);
        for (VillageEntranceExit villageEntranceExit : resultList) {
            Map<String, Object> tmp = new HashMap<>(5);
            tmp.put("villageCode", villageEntranceExit.getVillageCode());
            tmp.put("name", villageEntranceExit.getName());
            if (villageEntranceExit.getLon() != null) {
                tmp.put("lon", new BigDecimal(villageEntranceExit.getLon()).toString());
            } else {
                tmp.put("lon", null);
            }
            if (villageEntranceExit.getLat() != null) {
                tmp.put("lat", new BigDecimal(villageEntranceExit.getLat()).toString());
            } else {
                tmp.put("lat", null);
            }
            tmp.put("picUrl", villageEntranceExit.getPicUlr());
            list.add(tmp);
        }
        return list;

    }

    /**
     * @Description: 查询小区信息
     * @param: [map]
     * @return: java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
     * @author: minsheng
     * @date: 2019/1/9 13:54
     */
    @Override
    public List<Map<String, Object>> listVillagesByVillageCode (Map<String, Object> map) {
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            List<Village> resultList = villageDao.listVillagesByVillageCode(map);
            for (Village village : resultList) {
                Map<String, Object> tmp = new HashMap<>(5);
                tmp.put("villageCode", village.getVillageCode());
                tmp.put("villageName", village.getVillageName());
                if (village.getLon() != null) {
                    tmp.put("lon", new BigDecimal(village.getLon()).toString());
                } else {
                    tmp.put("lon", null);
                }
                if (village.getLat() != null) {
                    tmp.put("lat", new BigDecimal(village.getLat()).toString());
                } else {
                    tmp.put("lat", null);
                }
                tmp.put("address", village.getAddress());
                tmp.put("picUrl", village.getPicUrl());
                tmp.put("buildingNum", village.getBuildingNum());
                tmp.put("houseNum", village.getHouseNum());
                list.add(tmp);
            }
            return list;
        } catch (Exception e) {
            throw new BusinessException(ExceptionCode.VILLAGE_SQL_EXCEPTION_CODE, "根据小区编号查询小区信息出错。");
        }
    }

    /**
     * @Description: 获得小区上层最高层组织区划
     * @param: []
     * @return: java.util.List<com.smartcommunity.entity.face.OrganizationVillage>
     * @author: minsheng
     * @date: 2019/1/9 13:53
     */
    @Override
    public List<OrganizationVillage> OrganizationVillageOneID () {
        List<OrganizationVillage> organizationList = villageDao.OrganizationVillageOneID();
        return organizationList;
    }


    //加载每个小区关联的楼栋数据
    public void loadBuildToTreeData(List<Village> villageList){
        for(Village village :villageList){
            Build build = new Build();
            build.setVillageCode(village.getVillageCode());
            village.setBuildList(villageDao.listBuilds(build));
        }
    }

    /**
     * 获取行政区划树
     * @param param
     * @return
     */
    public OrganizationVillage getOrganization (Map<String, Object> param) {
        OrganizationVillage organization = (OrganizationVillage) param.get("organizationVillage");
        if (organization != null) {
            //获取子行政区划
            param.put("id", organization.getId());
            organization.setChildren(getOrganizationByChildrenId(param));
        }
        return organization;

    }

    private List<OrganizationVillage> getOrganizationByChildrenId (Map<String, Object> param) {
        Integer id = (Integer) param.get("id");
        List<OrganizationVillage> list = new ArrayList<>();
        //获取子行政区划
        List<OrganizationVillage> organizationList = villageDao.listOrganizationVillageByChildrenId(id);
        if (organizationList == null || organizationList.size() == 0) {
            return list;
        }

        for (OrganizationVillage organization : organizationList) {
            // 递归遍历子组织区划
            param.put("id", organization.getId());
            organization.setChildren(getOrganizationByChildrenId(param));
            list.add(organization);
        }
        return list;
    }


    private List<CommonDevice> getDeviceList (String villageCode) {
        List<CommonDevice> commonDeviceList1 = deviceDao.queryCameraList(villageCode);
        List<CommonDevice> commonDeviceList2 = deviceDao.queryWifiList(villageCode);
        List<CommonDevice> commonDeviceList3 = deviceDao.queryManholeCoverList(villageCode);
        List<CommonDevice> commonDeviceList4 = deviceDao.queryAcList(villageCode);
        List<CommonDevice> commonDeviceList5 = deviceDao.querySenseList(villageCode);
        List<CommonDevice> commonDeviceList = new ArrayList<>();
        commonDeviceList.addAll(commonDeviceList1);
        commonDeviceList.addAll(commonDeviceList2);
        commonDeviceList.addAll(commonDeviceList3);
        commonDeviceList.addAll(commonDeviceList4);
        commonDeviceList.addAll(commonDeviceList5);
        return commonDeviceList;
    }


    /**
     * 获取小区基本信息ALL
     *
     * @param param 数据权限小区集
     * @return 获取当前用户分配的权限小区
     */
    @Override
    public List<Village> getAllVillage (Map<String, Object> param) {
        List<Village> villageList = villageDao.getAllVillage(param);
        return villageList;
    }


    /**
     * 行政区划数据新增
     *
     * @param bean
     * @return json
     */
    @Override
    @Transactional
    public Result insertVillageOrg (OrganizationVillage bean) {
        if (bean == null) {
            throw new BusinessException(ResultCode.DATA_LOSE);
        }
        Map<String, Object> map = new HashMap<>(3);
        map.put("id", bean.getId());
        map.put("orgName", bean.getOrgName());
        map.put("orgCode", bean.getOrgCode());

        //行政区划编码必须是数字
        if (!ToolString.isNumeric(bean.getOrgCode())) {
            throw new BusinessException(ResultCode.VILLAGE_ORG_CODE_NOT_NUMERIC);
        }

        //入库校验
        checkVillageOrg(map, bean.getParentId());

        //入库
        bean.setPinyin(ToolPinyin.getPinYinHeadChar(bean.getOrgName()));
        villageDao.insertVillageOrg(bean);

        //新增角色关联的行政区划code
        addRelRoleVillage(bean.getOrgCode());
        return Result.ok();
    }

    /**
     * 行政区划校验
     *
     * @param map
     * @return json
     */
    public void checkVillageOrg (Map<String, Object> map, Integer parentId) {
        //校验行政区划名称和CODE
        List<Map<String, Object>> returnList = villageDao.checkVillageOrgNameRepeat(map);
        //行政区划有小区，则不让再添加行政区划
        List<Map<String, Object>> returnVillageList = villageDao.checkOrgHaveVillage(parentId);
        if ((Long) returnList.get(0).get("nameCount") >=1) {
            throw new BusinessException(ResultCode.VILLAGE_ORG_NAME_EXSIT);
        }
        if ((Long) returnList.get(0).get("codeCount") >= 1) {
            throw new BusinessException(ResultCode.VILLAGE_ORG_CODE_EXSIT);
        }
        if ((Long) returnList.get(0).get("villageCodeCount") >= 1) {
            throw new BusinessException(ResultCode.VILLAGE_ORG_CODE_VILLAGECODE_EXSIT);
        }
        if ((Long) returnVillageList.get(0).get("villageCount") >= 1) {
            throw new BusinessException(ResultCode.VILLAGE_ORG_VIL_EXSIT_ADD);
        }
    }


    /**
     * 行政区划数据更新
     *
     * @param bean
     * @return json
     */
    @Override
    @Transactional
    public Result updateVillageOrg (OrganizationVillage bean) {
        if (bean == null || bean.getId() == null) {
            throw new BusinessException(ResultCode.DATA_LOSE);
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", bean.getId());
        map.put("orgName", bean.getOrgName());

        //行政区划编码必须是数字
        if (!ToolString.isNumeric(bean.getOrgCode())) {
            throw new BusinessException(ResultCode.VILLAGE_ORG_CODE_NOT_NUMERIC);
        }
        //数据校验
        checkVillageOrg(map, bean.getParentId());
        bean.setPinyin(ToolPinyin.getPinYinHeadChar(bean.getOrgName()));
        String orgCode = villageDao.getOrgCodeById(bean.getId().toString());
        villageDao.updateVillageOrgByPrimaryKey(bean);
        delRelRoleVillage(orgCode);
        addRelRoleVillage(bean.getOrgCode());
        return Result.ok();
    }


    @Override
    @Transactional
    public Result deleteVillageOrg (String ids) {
        if (ids == null) {
            throw new BusinessException(ResultCode.DATA_LOSE);
        }
        //获取机构MAP信息
        Map<Integer,String> orgNameMap = new HashMap<>();
        Map<Integer,String> orgCodeMap = new HashMap<>();
        List<OrganizationVillage> orgList = villageDao.getVillageOrgByOrgIds(ids);
        for(OrganizationVillage org :orgList){
            orgNameMap.put(org.getId(),org.getOrgName());
            orgCodeMap.put(org.getId(),org.getOrgCode());

        }
        int [] idArrays = ArrayUtils.toIntArray(ids);
        //数据校验
        Result result = checkOrgHaveVillage(idArrays,orgNameMap);
        if(result.getResultCode() != ResultCode.SUCCESS.code()){
            return  result;
        }

        for (int id :idArrays){
            String orgCode = orgCodeMap.get(id);
            //删除行政区划
            villageDao.deleteVillageOrgByPrimaryKey(id);
            //删除角色关联的行政区划code
            delRelRoleVillage(orgCode);
        }
        return Result.ok();
    }

    /**
     * 区划删除校验
     * @param id
     */
    public void checkOrgHaveVillage (Integer id) {
        List<Map<String, Object>> returnList = villageDao.checkOrgHaveVillage(id);
        if ((Long) returnList.get(0).get("childrenCount") >= 1) {
            throw new BusinessException(ResultCode.VILLAGE_ORG_ORG_EXSIT_DEL);
        }
        if ((Long) returnList.get(0).get("villageCount") >= 1) {
            throw new BusinessException(ResultCode.VILLAGE_ORG_VIL_EXSIT_DEL);
        }
    }


    /**
     * 区划删除校验
     * @param idArrays
     */
    public Result checkOrgHaveVillage (int [] idArrays,Map<Integer,String> orgMap) {
        Result result = new Result();
        StringBuffer msg = new StringBuffer();
        //转换id数组，支持批量删除
        for (int id : idArrays){
            List<Map<String, Object>> returnList = villageDao.checkOrgHaveVillage(id);
            if ((Long) returnList.get(0).get("childrenCount") >= 1) {
                result.setResultCode(ResultCode.VILLAGE_ORG_ORG_EXSIT_DEL.code());
                result.setResultMessage(msg.append("[").append(orgMap.get(id)).append("]").append(ResultCode.VILLAGE_ORG_ORG_EXSIT_DEL.getMsg()).toString());
                break;
            }
            if ((Long) returnList.get(0).get("villageCount") >= 1) {
                result.setResultCode(ResultCode.VILLAGE_ORG_VIL_EXSIT_DEL.code());
                result.setResultMessage( msg.append("[").append(orgMap.get(id)).append("]").append(ResultCode.VILLAGE_ORG_VIL_EXSIT_DEL.getMsg()).toString());
                break;
            }
        }
        return result;
    }



    /**
     * @Description: 新增小区
     * @param: [Village]
     * @return: Result
     * @author: zdy
     * @date: 2020/1/8
     */
    @Transactional
    @Override
    public Result insertVillage (Village bean) {
        if (bean == null) {
            throw new BusinessException(ResultCode.DATA_LOSE);
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("villageCode", bean.getVillageCode());
        map.put("villageName", bean.getVillageName());
        map.put("parentId",bean.getParentId());

        //查看当前授权的小区数量
        Integer allowdVillageCount = getVillageCount();

        //查看已存在的小区数量
        int villageCount = villageDao.getVillageCount();
        log.info("allowdVillageCount:{}",allowdVillageCount);
        if (allowdVillageCount <= villageCount  && villageCount != -1) {
            throw new BusinessException(ResultCode.VILLAGE_OVERRUN);
        }

        //必须在行政区划末端添加
        List<Map<String, Object>> returnOrgList = villageDao.checkOrgHaveVillage(Integer.valueOf(bean.getParentId()));
        if ((Long) returnOrgList.get(0).get("childrenCount") >= 1) {
            throw new BusinessException(ResultCode.VILLAGE_ADD_ON_END);
        }

        //小区code只能为数字
        if(!ToolString.isNumeric(bean.getVillageCode())){
            throw new BusinessException(ResultCode.VILLAGE_CODE_NOT_NUMERIC);
        }
        List<Map<String, Object>> returnList = villageDao.checkInsertVillage(map);
        if(CollectionUtils.isNotEmpty(returnList)) {
	        //判断code是否存在
	        if ((Long) returnList.get(0).get("codeCount") >= 1) {
	            throw new BusinessException(ResultCode.VILLAGE_CODE_EXSIT);
	        }
	        //判断所在的行政区划下小区名称是否存在
	        if ((Long) returnList.get(0).get("nameCount") >= 1) {
	            throw new BusinessException(ResultCode.VILLAGE_NAME_EXSIT);
	        }
	        //判断和行政区划code重复
	        if ((Long) returnList.get(0).get("orgCodeCount") >= 1) {
	            throw new BusinessException(ResultCode.VILLAGE_CODE_ORGCODE_EXSIT);
	        }
	        //判断行政区划是否存在
	        if ((Long) returnList.get(0).get("parentIdCount") !=1) {
	            throw new BusinessException(ResultCode.VILLAGE_ORG_NOT_EXSIT);
	        }
        }
        bean.setPinyin(ToolPinyin.getPinYinHeadChar(bean.getVillageName()));
        //小区
        villageDao.insertVillage(bean);

        //小区出入口
        List<VillageEntranceExit> entranceExitList = bean.getEntranceExitList();
        if(entranceExitList!=null && !entranceExitList.isEmpty()){
            villageDao.insertVillageEntranceExits(entranceExitList);
        }

        // 把新增小区添加到缓存和数据权限表
        CacheMap.VILLAGE_INFO_MAP.put(bean.getVillageCode(), bean);

        // 新增到关联的角色
        addRelRoleVillage(bean.getVillageCode());
        return Result.ok();
    }

    /**
     * @Description: 小区数据更新
     * @param: [Village]
     * @return: Result
     * @author: zdy
     * @date: 2020/1/8
     */
    @Transactional
    @Override
    public Result updateVillage (Village bean) {
        if (bean == null || StringUtils.isEmpty(bean.getVillageCode())) {
            throw new BusinessException(ResultCode.DATA_LOSE);
        }
        Map<String, Object> map = new HashMap<>(3);
        map.put("villageCode", bean.getVillageCode());
        map.put("villageName", bean.getVillageName());
        map.put("parentId", bean.getParentId());

        //必须在行政区划末端添加
        List<Map<String, Object>> returnOrgList = villageDao.checkOrgHaveVillage(Integer.valueOf(bean.getParentId()));
        if ((Long) returnOrgList.get(0).get("childrenCount") >= 1) {
            throw new BusinessException(ResultCode.VILLAGE_ADD_ON_END);
        }
        List<Map<String, Object>> returnList = villageDao.checkUpdateVillage(map);

        //当前行政区划下名称是否重复
        if ((Long) returnList.get(0).get("nameCount") >= 1) {
            throw new BusinessException(ResultCode.VILLAGE_NAME_EXSIT);
        }
        //请求的行政区划是否存在
        if ((Long) returnList.get(0).get("parentIdCount") != 1) {
            throw new BusinessException(ResultCode.VILLAGE_ORG_NOT_EXSIT);
        }

        bean.setMrowTime(ToolDateTime.getDate());
        bean.setPinyin(ToolPinyin.getPinYinHeadChar(bean.getVillageName()));
        villageDao.updateVillage(bean);

        if(bean.getEntranceExitList()!=null && bean.getEntranceExitList().size()>0){
            //小区出入口 更新覆盖
            villageDao.deleteVillageEntranceExit(bean.getVillageCode());
            villageDao.insertVillageEntranceExits(bean.getEntranceExitList());
        }
        //修改es数据
        try {
             peopleService.syncDataToEs( bean.getVillageCode(), null);
        } catch (Exception e) {
            log.error("更新实有人口失败，入库ES异常"+e);

        }
        // 修改小区成功后重新赋值给redis缓存
        CacheMap.VILLAGE_INFO_MAP.put(bean.getVillageCode(), bean);
        return Result.ok();
    }

    /**
     * @Description: 删除小区
     * @param: [villageCode]
     * @return: Result
     * @author: zdy
     * @date: 2020/1/8
     */
    @Transactional
    @Override
    public Result deleteVillage (String villageCode) {
        if (villageCode == null) {
            throw new BusinessException(ResultCode.DATA_LOSE);
        }
        People people = new People();
        people.setVillageCode(villageCode);
        // 查看小区是否有人员数据
        int count = peopleDao.countPeoplesByVillageCode(villageCode);
        if (count > 0) {
            throw new BusinessException(ResultCode.VILLAGE_HAVE_DATA);
        }
        // 删除小区
        villageDao.deleteVillage(villageCode);
        // 删除小区后再删除该小区的一标六实数据
        sixEntityDao.deleteSixEntity(villageCode);
        // 删除小区与区划关系表
        villageDao.deleteVillageOrgByVillage(villageCode);
        // 删除小区出入口
        villageDao.deleteVillageEntranceExit(villageCode);
        // 删除小区楼栋
        villageDao.deleteVillageBuildingByCode(villageCode);
        // 删除小区房屋
        Map<String, Object> map = new HashedMap();
        map.put("villageCode",villageCode);
        houseDao.deleteHouseByVillageCode(map);
        // 删除小区人房关系
        houseDao.deleteRelPeopleHouseByVillageCode(map);
        // 删除小区设备
        cameraDao.deleteCameraByVillageCode(villageCode);
        // 删除单位数据
        realCompanyDao.deleteRealCompanyByVillageCode(villageCode);
        // 删除实有力量
        realPowerOrgDao.deleteRealPowerByVillageCode(villageCode);

        // 删除缓存里的小区数据
        CacheMap.VILLAGE_INFO_MAP.remove(villageCode);

        // 删除角色对应的小区
        delRelRoleVillage(villageCode);
        return Result.ok();
    }

    /**
     * @Description: 获取小区组织区划
     * @param: [map, currentPage, pageSize]
     * @return: com.smartcommunity.base.bean.Pager<com.smartcommunity.entity.face.OrganizationVillage>
     * @author: minsheng
     * @date: 2019/1/9 13:48
     */
    @Override
    public Pager<OrganizationVillage> pageVillageOrg (Map<String, Object> map, int currentPage, int pageSize) {
        PageHelper.startPage(currentPage, pageSize);
        List<OrganizationVillage> villageOrgList = villageDao.getVillageOrgList(map);
        int totalNum = (int) ((Page<OrganizationVillage>) villageOrgList).getTotal();
        Pager<OrganizationVillage> villageOrgPager = new Pager<>(currentPage, pageSize, totalNum);
        villageOrgPager.setList(villageOrgList);
        return villageOrgPager;
    }

    /**
     * @Description: 查询小区集合
     * @param: [map, currentPage, pageSize]
     * @return: com.smartcommunity.base.bean.Pager<com.smartcommunity.entity.face.Village>
     * @author: minsheng
     * @date: 2019/1/9 13:48
     */
    @Override
    public Pager<Village> pageVillages (Map<String, Object> map, int currentPage, int pageSize) {
        PageHelper.startPage(currentPage, pageSize);
        List<Village> villageList = villageDao.getVillageList(map);
        int totalNum = (int) ((Page<Village>) villageList).getTotal();
        Pager<Village> villagePager = new Pager<>(currentPage, pageSize, totalNum);
        villagePager.setList(villageList);
        return villagePager;
    }
    @Override
    public Pager<VillageForPeopleManage> pageVillagesForPeopleManage (Map<String, Object> map, int currentPage, int pageSize) {
        PageHelper.startPage(currentPage, pageSize);
        List<VillageForPeopleManage> villageList = villageDao.getVillageListForPeopleManage(map);
        int totalNum = (int) ((Page<VillageForPeopleManage>) villageList).getTotal();
        Pager<VillageForPeopleManage> villagePager = new Pager<>(currentPage, pageSize, totalNum);
        villagePager.setList(villageList);
        return villagePager;
    }

    /**
     * @Description: 根据小区编号查询小区信息
     * @param: [villageCode]
     * @return: com.smartcommunity.entity.face.Village
     * @author: minsheng
     * @date: 2019/1/9 13:49
     */
    @Override
    public Village getVillage (String villageCode) {

        Village village =villageDao.getVillage(villageCode);
        Map<String,Object> params = new HashedMap();
        params.put("villageCode",villageCode);
        List<VillageEntranceExit> list= villageDao.getVillageEntranceExitList(params);
        village.setEntranceExitList(list);
        return village;
    }

    @Override
    public Result addBuilding (Building building) {
        verifyBuilding(building);
        //检查楼栋是否重复
        int count = villageDao.checkAddBuilding(building);
        if (count > 0) {
            return Result.error(ResultCode.VILLAGE_BUILD_EXSIT);
        }
        villageDao.addBuilding(building);
        return Result.ok();
    }

    /**
     * 校验building
     */
    private void verifyBuilding(Building building) {
        if (StringUtils.isEmpty(building.getBuildingNo())) {
            throw new BusinessException(ResultCode.VILLAGE_BUILD_NOT_EMPTY);
        }
        if (building.getBuildingNo().length() > 60) {
            throw new BusinessException(ResultCode.VILLAGE_BUILD_TOO_LONG);
        }
    }


    /**
     * @Description: 更新楼栋数据
     * @param: [build]
     * @return: void
     * @author: minsheng
     * @date: 2019/1/9 13:49
     */
    @Override
    public Result updateBuild (Building build) {
        verifyBuilding(build);
        Building bu = villageDao.getBuildingById(String.valueOf(build.getId()));
        if(bu ==null){
            return Result.error(ResultCode.VILLAGE_BUILD_NOT_EXSIT);
        }
        //检查此楼栋下有没有房屋
        House house = new House();
        house.setVillageCode(bu.getVillageCode());
        house.setBuildingNo(bu.getBuildingNo());
        List<House> houseList = villageDao.listHousesByBuilding(house);
        if(CollectionUtils.isNotEmpty(houseList)){
            return Result.error(ResultCode.VILLAGE_BUILD_HAVE_HOUSE);
        }

        //检查楼栋是否重复
        int count = villageDao.checkUpdateBuilding(build);
        if(count>0){
            return Result.error(ResultCode.VILLAGE_BUILD_EXSIT);
        }
        //更新楼栋信息
        villageDao.updateBuild(build);
        return Result.ok();
    }

    /**
     * @Description: 删除楼栋数据
     * @param: [id]
     * @return: void
     * @author: minsheng
     * @date: 2019/1/9 13:50
     */
    @Override
    @Transactional
    public Result deleteBuild (String ids) {
        if(StringUtils.isBlank(ids)){
            return Result.error(ResultCode.DATA_LOSE);
        }

        List<String> list = new ArrayList<>();
        StringBuffer msg = new StringBuffer();
        for(String id :ids.split(",")){
            //根据id获取楼栋信息
            Building building = villageDao.getBuildingById(id);
            if(building==null){
                continue;
            }
            //检查此楼栋下有没有房屋
            House house = new House();
            house.setVillageCode(building.getVillageCode());
            house.setBuildingNo(building.getBuildingNo());
            List<House> houseList = villageDao.listHousesByBuilding(house);
            if(CollectionUtils.isNotEmpty(houseList)){
                msg.append(building.getBuildingNo()).append(",");
               continue;
            }
            list.add(id);
        }
        //提示删除失败的楼栋信息
        if(msg.length()>0){
            return Result.error(ResultCode.VILLAGE_BUILD_HAVE_HOUSE_DELETE.code(),
                    String.format(ResultCode.VILLAGE_BUILD_HAVE_HOUSE_DELETE.msg(), msg.substring(0,msg.length()-1)));
        }
        //删除楼栋信息
        if(list.size()>0){
            villageDao.deleteBuild(ArrayUtils.toString(list));
        }
        return Result.ok();
    }

    /**
     * @Description: 查询小区出入口集合
     * @param: [map, currentPage, pageSize]
     * @return: com.smartcommunity.base.bean.Pager<com.smartcommunity.entity.face.VillageEntranceExit>
     * @author: minsheng
     * @date: 2019/1/9 13:50
     */
    @Override
    public Pager<VillageEntranceExit> pageVillageEntranceExits (Map<String, Object> map, int currentPage, int pageSize) {
        PageHelper.startPage(currentPage, pageSize);
        List<VillageEntranceExit> villageEntranceExitList = villageDao.getVillageEntranceExitList(map);
        int totalNum = (int) ((Page<VillageEntranceExit>) villageEntranceExitList).getTotal();
        Pager<VillageEntranceExit> villageEntranceExitListPager = new Pager<>(currentPage, pageSize, totalNum);
        villageEntranceExitListPager.setList(villageEntranceExitList);
        return villageEntranceExitListPager;
    }

    /**
     * @Description: 新增小区出入口数据
     * @param: [villageEntranceExit]
     * @return: void
     * @author: minsheng
     * @date: 2019/1/9 13:50
     */
    @Override
    public Result insertVillageEntranceExit (VillageEntranceExit villageEntranceExit) {
        // 出入口同小区名称校验
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("villageCode", villageEntranceExit.getVillageCode());
        paramMap.put("name", villageEntranceExit.getName());
        Integer resultI = villageDao.checkVillageEntranceExitNameRepeat(paramMap);
        if (resultI > 0) {
            throw new BusinessException(ResultCode.ENTRANCE_EXIT_NAME_EXSIT);
        }
        villageDao.insertVillageEntranceExit(villageEntranceExit);
        return Result.ok();
    }

    /**
     * @Description: 更新小区出入口数据
     * @param: [villageEntranceExit]
     * @return: void
     * @author: minsheng
     * @date: 2019/1/9 13:51
     */
    @Override
    public Result updateVillageEntranceExit (VillageEntranceExit villageEntranceExit)  {
        // 出入口同小区名称校验
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("villageCode", villageEntranceExit.getVillageCode());
        paramMap.put("name", villageEntranceExit.getName());
        paramMap.put("id", villageEntranceExit.getId());
        Integer resultI = villageDao.checkVillageEntranceExitNameRepeat(paramMap);
        if (resultI > 0) {
            throw new BusinessException(ResultCode.ENTRANCE_EXIT_NAME_EXSIT);
        }
        villageDao.updateVillageEntranceExit(villageEntranceExit);
        return Result.ok();
    }

    /**
     * @Description: 删除小区出入口数据
     * @param: [id]
     * @return: void
     * @author: minsheng
     * @date: 2019/1/9 13:51
     */
    @Override
    public Result deleteVillageEntranceExit (String id) {
        villageDao.deleteVillageEntranceExitById(id);
        return Result.ok();
    }


    @Override
    public Pager<Village> pageVillageByParentId (Map<String, String> map, int currentPage, int pageSize) {
        try {
            PageHelper.startPage(currentPage, pageSize);
            List<Village> villageList = villageDao.listVillageByParentId(map);
            int totalNum = (int) ((Page<Village>) villageList).getTotal();
            Pager<Village> villagePager = new Pager<>(currentPage, pageSize, totalNum);
            villagePager.setList(villageList);
            return villagePager;
        } catch (Exception e) {
            throw new BusinessException(ExceptionCode.VILLAGE_SQL_EXCEPTION_CODE, "根据父ID获取小区列表出错！");
        }
    }

    @Override
    public List<Village> listVillagesByOrgId (Map<String, Object> map) {
        try {
            return villageDao.listVillagesByOrgId(map);
        } catch (Exception e) {
            throw new BusinessException(ExceptionCode.VILLAGE_SQL_EXCEPTION_CODE, "根据orgId获取小区信息出错！");
        }
    }


    @Override
    public List<SysVillage> queryAllVillage() {
        SysVillageExample example = new SysVillageExample();
        example.setOrderByClause("villageName desc");
        return sysVillageMapper.selectByExample(example);
    }

    @Override
    public List<OrganizationVillage> listVillageTree(Map<String, Object> param) {
        List<OrganizationVillage> result = new ArrayList<>();
        Map<Integer, OrganizationVillage> mapOrgId = new HashMap<>();
        Map<String, OrganizationVillage> mapOrgCode = new HashMap<>();
        Map<String, Village> mapVillageCode = new HashMap<>();
        Map<String,Object> parMap = new HashedMap();
        if (param.get("villageCode") != null && param.get("villageCode") != "") {
            String codes = param.get("villageCode").toString().replaceAll("'", "");
            Set orgSet = getOrgIdsByVillageCode(codes);
            if(CollectionUtils.isEmpty(orgSet)){
                return result;
            }
            Object[] array = orgSet.toArray();
            String ids = StringUtils.join(array, ",");
            parMap.put("ids", ids);
        }
        //查询所有的行政区划
        List<OrganizationVillage> allOrgList = villageDao.getVillageOrgList(parMap);
        //将组织机构信息放置到Map中
        for (OrganizationVillage org : allOrgList) {
            mapOrgId.put(org.getId(), org);
            mapOrgCode.put(org.getOrgCode(), org);
        }
        //1.查询有权限的小区
        List<Village> villageList = villageDao.getVillageListByParentId(param);//查找所有具有权限的小区
        //将有权限的组织机构挂到树上
//        if (param.get("villageCode") != null) {
//            String codes = param.get("villageCode").toString().replaceAll("'", "");
//            if (StringUtils.isNotEmpty(codes)) {
//                List<String> hasPermissionVillageList = ArrayUtils.toStringList(codes);
//                for (String code : hasPermissionVillageList) {
//                    if (mapOrgCode.containsKey(code)) {
//                        OrganizationVillage parentOrg = mapOrgCode.get(code);
//                        //绑定上级组织机构
//                        buildUpOrg(result, mapOrgId, parentOrg);
//                    }
//                }
//            }
//        }else{
//            //跳过权限
            for(OrganizationVillage org :allOrgList){
                 if(org.getParentId()==-1){
                     result.add(org);
                 }else{
                     OrganizationVillage parentOrg= mapOrgId.get(org.getParentId());
                     if(parentOrg!=null ) { //当org.getChildren().contains(parentOrg)为true
                         if(parentOrg.getChildren()==null){
                             parentOrg.setChildren(new ArrayList<>());
                         }
                         parentOrg.getChildren().add(org);
                     }
                 }
            }
//        }
        //2.根据小区找到有权限小区的行政区划,将小区挂到行政区划上；
        for (Village village : villageList) {
            if (mapOrgId.containsKey(village.getParentId())) {
                OrganizationVillage parentOrg = mapOrgId.get(village.getParentId());
                if (parentOrg.getVillageList() == null) {
                    parentOrg.setVillageList(new ArrayList<>());
                }
                if (!parentOrg.getVillageList().contains(village)) {
                    parentOrg.getVillageList().add(village);
                    //绑定上级组织机构
                    buildUpOrg(result, mapOrgId, parentOrg);
                }
            }
            village.setIsDevice(0);
            mapVillageCode.put(village.getVillageCode(), village);
        }
        //3.构造楼栋信息
        if (Boolean.parseBoolean(param.get("build").toString())) {
            String codes = "";
            if (param.get("villageCode") != null) {
                codes = param.get("villageCode").toString().replaceAll("'", "");
            }
            Build build = new Build();
            build.setVillageCode(codes);
            List<Build> buildList = villageDao.listBuilds(build);
            for (Build building : buildList) {
                if (mapVillageCode.containsKey(building.getVillageCode())) {
                    Village village = mapVillageCode.get(building.getVillageCode());
                    if (village.getBuildList() == null) {
                        village.setBuildList(new ArrayList<>());
                    }
                    if (!village.getBuildList().contains(building)) {
                        village.getBuildList().add(building);
                    }
                }
            }
        }

        //4.构造设备信息
        if (Boolean.parseBoolean(param.get("camera").toString())) {
            String codes = "";
            if (param.get("villageCode") != null) {
                codes = param.get("villageCode").toString().replaceAll("'", "");
            }
            List<Camera> cameraList= cameraDao.checkHaveCameraInVillage(codes,null,null);
            for(Camera camera :cameraList){
                if (mapVillageCode.containsKey(camera.getVillageCode())) {
                    Village village = mapVillageCode.get(camera.getVillageCode());
                    village.setIsDevice(1);
                }
            }
        }
        return result;
    }

    private void buildUpOrg(List<OrganizationVillage> result, Map<Integer, OrganizationVillage> mapOrgId, OrganizationVillage parentOrg) {
        if(parentOrg.getParentId()==-1&& !result.contains(parentOrg)) {//根组织
                result.add(parentOrg);
        }else{
            OrganizationVillage org= mapOrgId.get(parentOrg.getParentId());
            if(org!=null ){ //当org.getChildren().contains(parentOrg)为true 说明已经添加过了，不需要再递归
                if(org.getChildren()==null||!org.getChildren().contains(parentOrg)) {
                    buildUpOrg(result, mapOrgId, org);
                    if(org.getChildren()==null){
                        org.setChildren(new ArrayList<>());
                    }
                    org.getChildren().add(parentOrg);
                }
            }
        }
    }


    /**
     * 根据小区编号获取所有的楼栋
     * @param villageCode
     * @return
     */
    public List<String> getBuildNosByVillageCode(String villageCode){
        Building build = new Building();
        build.setVillageCode(villageCode);
        List<Building> list = villageDao.listBuildings(build);
        List<String> buildNos = list.stream().map(item->item.getBuildingNo()).collect(Collectors.toList());
        return buildNos;
    }
    public Map<String,Building> getBuildMapByVillageCode(String villageCode){
        Map<String,Building>  map = new HashMap<>();
        Building build = new Building();
        build.setVillageCode(villageCode);
        List<Building> list = villageDao.listBuildings(build);
        map = list.stream().collect(
                Collectors.toMap(Building::getBuildingNo, (p) -> p));
        return map;
    }


    /**
     * 根据小区编号、楼栋编号获取所有的房屋编号
     * @param villageCode
     * @return
     */
    public List<String> getHouseNosByVillageCode(String villageCode,List<String> buildNos){
        Map<String, String> map = new HashedMap();
        map.put("villageCode", villageCode);
        List<House> houseList = villageDao.listHouseNos(map);
        List<String> houseNos = houseList.stream().filter(item->buildNos.contains(item.getBuildingNo())).
                map(item->item.getHouseNo()).collect(Collectors.toList());
        return houseNos;
    }

    @Override
    public int queryVillagePeopleManageInfo(String villageCode) {
        //查询实有人口数据
        People people = new People();
        people.setVillageCode(villageCode);
        people.setSourceSyrk("1");
        int realPeopleCount = peopleDao.countPeoples(people);
        return 0;
    }

    /**
     * 新增关联权限 行政区划或者小区code
     * @param code
     */
    public void addRelRoleVillage(String code){
        User user = getCurrenUser();
        if (user != null) {
            if(!user.isAdmin()){
                Role role = new Role();
                role.setId(1);//管理员角色
                user.getRoleList().add(role);
            }
            Map<String,Object> param = new HashedMap();
            param.put("roleIds",user.getRoleList().stream().map(item-> item.getId()).collect(Collectors.toList()));
            param.put("villageCode",code);
            userApi.addRelRoleVillage(param);
        }
    }

    /**
     * 删除关联权限 行政区划或者小区code
     * @param code
     */
    public void delRelRoleVillage(String code){
        User user = getCurrenUser();
        if (user != null) {
            if(!user.isAdmin()){
                Role role = new Role();
                role.setId(1);//管理员角色
                user.getRoleList().add(role);
            }
            Map<String,Object> param = new HashedMap();
            param.put("roleIds",user.getRoleList().stream().map(item-> item.getId()).collect(Collectors.toList()));
            param.put("villageCode",code);
            userApi.delRelRoleVillage(param);
        }
    }



    /**
     * 根据有权限的小区code 获取所有上级的行政区划id
     * @param villageCode
     * @return
     */
    public Set<String> getOrgIdsByVillageCode(String villageCode){
        Set<String> ids = new HashSet<>();
        Map<String,OrganizationVillage> map = new HashMap<>();
        long st=System.currentTimeMillis();
        //由于权限设计问题，villageCode包含小区ID和全选的行政区划ID
        //查询有权限小区的行政区划ID
        List<String> parentIds = villageDao.getParentIdsByVillageCode(villageCode);
        long speedTime=System.currentTimeMillis()-st;
        log.info("1.sql耗时:"+speedTime+"ms");

        //查询行政区划ID
        st=System.currentTimeMillis();
        List<String> orgIds = villageDao.getOrgIdsByOrgCode(villageCode);
        speedTime=System.currentTimeMillis()-st;
        log.info("2.sql耗时:"+speedTime+"ms");
        parentIds.addAll(orgIds);

        //list 去重
        LinkedHashSet<String> tmpSet = new LinkedHashSet<String>(parentIds.size());
        tmpSet.addAll(parentIds);
        parentIds.clear();
        parentIds.addAll(tmpSet);

        //查询所有的组织机构
        st=System.currentTimeMillis();
        List<OrganizationVillage> allOrgList = villageDao.getVillageOrgList(new HashedMap());
        speedTime=System.currentTimeMillis()-st;
        log.info("3.sql耗时:"+speedTime+"ms");
        st=System.currentTimeMillis();
        for (OrganizationVillage org:allOrgList) {
            map.put(org.getId().toString(),org);
        }
        for(String parentId : parentIds){
            if(!ids.contains(parentId)){
                addParentId(parentId,map,ids);
            }
        }
        speedTime=System.currentTimeMillis()-st;
        log.info("4.id拼装:"+speedTime+"ms");
        return ids;
    }
    private void addParentId(String orgid, Map<String, OrganizationVillage> map, Set<String> ids) {
        OrganizationVillage org = map.get(orgid);
        if(!ids.contains(orgid)){
            ids.add(orgid);
        }
        if(org!=null){
            if(org.getParentId()==-1&& !ids.contains(org.getId().toString())) {//根组织
                ids.add(org.getParentId().toString());
            }else{
                if(!ids.contains(org.getParentId().toString())){
                    addParentId(org.getParentId().toString(),map,ids);
                    ids.add(orgid);
                }
            }
        }
    }


    /**
     * 根据有权限的小区code 获取所有上级的行政区划id
     * @param villageCode
     * @return
     */
    public List<String> getOrgIdsByVillageCode2(String villageCode){
        List<String> ids = new ArrayList<>();
        //查询小区
        List<String> parentIds = villageDao.getParentIdsByVillageCode(villageCode);
        //查询行政区划
        List<String> orgIds = villageDao.getOrgIdsByOrgCode(villageCode);
        parentIds.addAll(orgIds);
        for(String parentId : parentIds){
            ids.add(parentId);
            ids.addAll(getParentIdsByParentId(parentId));
        }
        return ids;
    }

    public List<String> getParentIdsByParentId(String id){
        List<String> ids = new ArrayList<>();
        String  parentId = villageDao.getVillageOrgByParentId(id);
        if(StringUtils.isNotBlank(parentId)  && Integer.valueOf(parentId) != -1){
            ids.add(parentId);
            ids.addAll(getParentIdsByParentId(parentId));
        }
        return ids;
    }
    public String getAllChildOrgId(String parentId){
        return villageDao.getAllChildOrgId(parentId);
    }

    @Override
    public Integer getAllVillageCounts() {
        return villageDao.getVillageCount();
    }

    /**
     * 获取小区授权数量
     * @return
     */
    public int getVillageCount(){
        String auth = redissonClient.get("authInfo");
        Integer villageCount = 0;
        if(StringUtils.isEmpty(auth) || JSON.parseObject(auth, AuthInfo.class)==null){
            if(StringUtils.equals(secret,"fAlSe")){
                //查看当前授权的小区数量
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("key", "villageCount");
                List<SysParams> paramsList = systemDao.querySysParams(map);
                for (SysParams item : paramsList) {
                    villageCount = Integer.valueOf(item.getValue());
                }
            }else{
                throw new BusinessException(ResultCode.AUTH_ERROR);
            }
        }else{
            AuthInfo  authInfo = JSON.parseObject(auth, AuthInfo.class);
            villageCount = authInfo.getViliageCount();
        }
        return villageCount;
    }

    public Pager<Unit> pageUnits(UnitSearch model){
        PageHelper.startPage(model.getPageNumber(), model.getPageSize());
        List<Unit> unitList = villageDao.listUnitByBulidAndVillage(model.getVillageCode(),model.getBuildingNo());
        int totalNum = (int) ((Page) unitList).getTotal();
        Pager<Unit> pager = new Pager<>(model.getPageNumber(), model.getPageSize(), totalNum);
        PageHelper.startPage(model.getPageNumber(), model.getPageSize());
        pager.setList(unitList);
        return pager;
    }

    /**
     * 通过小区编号查找所有的房屋信息
     * @param villageCode
     * @return
     */
    @Override
	public Map<String, Map<String, List<String>>> getAllHousesByVillageCode(String villageCode) {
    	Map<String, Map<String, List<String>>> result = new HashMap<>();
    	Building build = new Building();
        build.setVillageCode(villageCode);
        //楼栋
        List<Building> buildings = villageDao.listBuildings(build);
        for(Building building:buildings) {
        	result.put(building.getBuildingNo(), new HashMap<>());
        }
        //单元
        List<Unit> units = villageDao.listUnitByBulidAndVillage(villageCode, null);
        for(Unit unit:units) {
        	if(result.containsKey(unit.getBuildingNo())) {
        		result.get(unit.getBuildingNo()).put(unit.getUnitNo(), new ArrayList<>());
        	}
        }
        //房间
        Map<String, String> map = new HashedMap();
        map.put("villageCode", villageCode);
        List<House> houses = villageDao.listHouseNos(map);
        for(House house:houses) {
        	if(result.containsKey(house.getBuildingNo())) {
        		Map<String, List<String>> unitMap = result.get(house.getBuildingNo());
        		if(unitMap!=null && unitMap.containsKey(house.getUnitNo())) {
        			unitMap.get(house.getUnitNo()).add(house.getHouseNo());
        		}
        	}
        }
		return result;
	}

    /**
     * 获取当前用户
     * @return
     */
    private User getCurrenUser() {
    	User user = null;
        Object obj =  httpSession.getAttribute(Constant.USER_KEY);
        if(obj!=null) {
            user = JSON.parseObject(JSONObject.toJSONString(obj), User.class);
        }
        return user;
    }

    //获取用户关联角色权限的小区ID及行政区划ID
    private String getVillageCodeByUser(User user){
        String villageCode = "";
        List<String> villageCodeList = new ArrayList<>();
        for (Role role: user.getRoleList()) {
            villageCode = CacheMap.REL_ROLE_VILLAGE.get(role.getId());
            if(StringUtils.isEmpty(villageCode)){
                continue;
            }
            villageCodeList.addAll(Arrays.asList(villageCode.split(",")));
        }
        villageCode = ArrayUtils.toString(villageCodeList);
        return villageCode;
    }

    @Override
    public List<StatisticsVillageDataResp> getStatisticsVillageList(Map<String, Object> map) {
        return villageDao.getStatisticsVillageList(map);
    }

    public List<Tree> villageTree(TreeSearchModel model) {
        String codes = model.getVillageCodes();

        List<Tree> result = new ArrayList<>();
        //1.查询所有的行政区划
        List<OrganizationVillage> allOrgList = null;
        User user = getCurrenUser();
        if(StringUtils.isEmpty(codes)&&!user.isAdmin()){
            codes = getVillageCodeByUser(user);
            if(StringUtils.isEmpty(codes)){
                return result;
            }
            if (model.getVillageCodes() != null && !"".equals(model.getVillageCodes())) {
                codes = model.getVillageCodes().replaceAll("'", "");
            }

        }
        if(model.isHaveOrg()){
            Map<String, Object> parMap = new HashMap<>();
            if(!user.isAdmin()){
                Set orgSet = getOrgIdsByVillageCode(codes);
                if(CollectionUtils.isEmpty(orgSet)){
                    return result;
                }
                Object[] array = orgSet.toArray();
                String ids = StringUtils.join(array, ",");
                parMap.put("ids", ids);
            }

            allOrgList = villageDao.getVillageOrgList(parMap);
        }
        //2.查询有权限的小区
        List<Village> villageList = null;
        if(model.isHaveVillage()) {
            Map<String, Object> param = new HashMap<>();
            param.put("villageCode", codes);
            villageList = villageDao.getVillageListByParentId(param);//查找所有具有权限的小区
        }
        //3，查询所有小区分组，一级分组下的设备
        List<VillageGroup> groups = null;
        codes = StringUtils.isNotEmpty(codes)?codes.replace("'",""):"";
        if(model.isHaveGroup()){
            groups = villageGroupDao.listGroup(codes,model.isHaveDevice(),model.isHaveCamera());
        }

        //4.构造设备信息
        List<Camera> cameraList= null ;
        if(model.isHaveCamera()){
            cameraList = cameraDao.listCameraInVillage(codes,model.getCameraType(),model.getSource());
        }
        List<AccessDevice> deviceList= null ;
        if(model.isHaveDevice()){
            deviceList = accessDeviceDao.getAccessDeviceByVillageCodes(codes);
        }
        if(!model.isHaveOrg()){
            result = bulidVillageTree(villageList,groups,cameraList,deviceList,model.isHaveDevice());
        }else{
            result =  bulidOrgTree(allOrgList,villageList,groups,cameraList,deviceList,model.isHaveDevice());
        }
        return result;
    }

    /**
     * 构建行政区划树
     * @param orgList 行政区划数据集
     * @param villageList 小区数据集
     * @param groupList 小区分组数据集
     * @param cameraList 设备列表数据集
     * @return
     */
    private List<Tree> bulidOrgTree(List<OrganizationVillage> orgList,List<Village> villageList,List<VillageGroup> groupList,List<Camera> cameraList,List<AccessDevice> deviceList,boolean haveDevice){
        List<Tree> treeList = new ArrayList<>();
        //构建小区树
        List<Tree> villageTree = bulidVillageTree(villageList,groupList,cameraList,deviceList,haveDevice);
        //先构建行政区划树
        if(!CollectionUtils.isEmpty(orgList)){
            for(OrganizationVillage org:orgList){
                if(org!=null){
                    Tree orgTree = new Tree(String.valueOf(org.getId()),String.valueOf(org.getId()),String.valueOf(org.getParentId())
                            ,org.getOrgName(),TreeTypeEnum.ORG.getTypeVal());
                    //构建行政区下的小区
                    if(!CollectionUtils.isEmpty(villageTree)){
                        for(Tree tree:villageTree){
                            if(tree.getParentId().equals(String.valueOf(org.getId()))){
                                if(orgTree.getItems() == null){
                                    orgTree.setItems(new ArrayList<>());
                                }
                                orgTree.getItems().add(tree);
                            }
                        }
                    }
                    treeList.add(orgTree);
                }
            }
        }
        TreeUtil treeUtil = new TreeUtil();
        return treeUtil.buildByRecursive(treeList,"-1");
    }

    /**
     * 构建小区设备树结构
     * @param villageList 小区数据集
     * @param groupList 分组数据集
     * @param cameraList 设备数据集
     * @return
     */
    private List<Tree> bulidVillageTree(List<Village> villageList,List<VillageGroup> groupList,List<Camera> cameraList,List<AccessDevice> deviceList,boolean haveDevice){
        List<Tree> treeList = new ArrayList<>();
        List<String> groupDeviceIds = new ArrayList<>();
        if(!CollectionUtils.isEmpty(villageList)){
            for(Village village:villageList){
                if(village!=null){
                    treeList.add(new Tree(String.valueOf(village.getVillageCode()),village.getVillageCode(),String.valueOf(village.getParentId())
                            ,village.getVillageName(),TreeTypeEnum.VILLAGE.getTypeVal()));
                }
            }
        }
        bulidGroupTree(groupList,treeList,groupDeviceIds);
        bulidCameraTree(cameraList,treeList,groupDeviceIds);
        if(haveDevice){
            bulidDeviceTree(deviceList,treeList,groupDeviceIds);
        }
        return treeList;
    }

    /**
     * 构建小区分组，以及分组下设备的分组
     * @param groupList 分组列表
     * @param treeList 已经构建成数列表的小区数据
     * @param groupDeviceIds 需要传递出去的小区分组下的数据
     */
    private void bulidGroupTree(List<VillageGroup> groupList, List<Tree> treeList,  List<String> groupDeviceIds){
        if(!CollectionUtils.isEmpty(groupList)){
            List<Tree> groups  = new ArrayList<>();
            for(VillageGroup group:groupList){
                Tree groupTree = new Tree(String.valueOf(group.getId()),String.valueOf(group.getId()),group.getParentId()==null?group.getVillageCode():String.valueOf(group.getParentId()),
                        group.getName(),TreeTypeEnum.VILLAGEGROUP.getTypeVal());
                if(!CollectionUtils.isEmpty(group.getGroupDevices())){
                    for(GroupDevice camera:group.getGroupDevices()){
                        if(camera!=null){
                            if(groupTree.getItems() == null){
                                groupTree.setItems(new ArrayList<>());
                            }
                            groupDeviceIds.add(camera.getId());
                            groupTree.getItems().add(new Tree(String.valueOf(camera.getId()),camera.getId(),String.valueOf(group.getId()),
                                    camera.getName(),TreeTypeEnum.CRAMERA.getTypeVal(),camera.getDeviceType(),camera.getSubType(),
                                    camera.getLon(),camera.getLat()));
                        }
                    }
                }
                groups.add(groupTree);
            }
            TreeUtil treeUtil = new TreeUtil();
            for(Tree tree:treeList){
                for(Tree greeTree:groups){
                    if(greeTree.getParentId()!=null&&greeTree.getParentId().equals(tree.getId())){
                        if(tree.getItems() == null){
                            tree.setItems(new ArrayList<>());
                        }
                        tree.getItems().add(treeUtil.findChildren(greeTree,groups));
                    }
                }
            }
        }
    }


    /**
     * 构建小区以及小区下设备的分组
     * @param cameraList 设备列表
     * @param treeList 已经构建成树结构的小区数据
     * @param groupDeviceIds 设备已经分配了分组需要先过滤掉
     */
    private void bulidCameraTree(List<Camera> cameraList,List<Tree> treeList,List<String> groupDeviceIds){
        if(!CollectionUtils.isEmpty(cameraList)&&!CollectionUtils.isEmpty(treeList)){
            for(Tree tree:treeList){
                for(Camera camera:cameraList){
                    if(camera!=null){
                        if(groupDeviceIds.contains(camera.getCameraId())){
                            continue;
                        }
                        if(tree.getId().equals(camera.getVillageCode())) {
                            Tree deviceTree = new Tree(String.valueOf(camera.getCameraId()), camera.getCameraId(), camera.getVillageCode(),
                                    camera.getName(), TreeTypeEnum.CRAMERA.getTypeVal(),camera.getDeviceType(),camera.getCameraType(),
                                    camera.getLon(),camera.getLat());
                            if (tree.getItems() == null) {
                                tree.setItems(new ArrayList<>());
                            }
                            tree.getItems().add(deviceTree);
                        }
                    }
                }
            }
        }
    }
    /**
     * 构建小区以及小区下设备的分组
     * @param deviceList RFid设备列表
     * @param treeList 已经构建成树结构的小区数据
     * @param groupDeviceIds 设备已经分配了分组需要先过滤掉
     */
    private void bulidDeviceTree(List<AccessDevice> deviceList,List<Tree> treeList,List<String> groupDeviceIds){
        if(!CollectionUtils.isEmpty(deviceList)&&!CollectionUtils.isEmpty(treeList)){
            for(Tree tree:treeList){
                for(AccessDevice device:deviceList){
                    if(device!=null){
                        if(groupDeviceIds.contains(device.getDeviceId())){
                            continue;
                        }
                        if(tree.getId().equals(device.getVillageCode())){
                            Tree deviceTree = new Tree(String.valueOf(device.getDeviceId()),device.getDeviceId(),device.getVillageCode(),
                                    device.getDeviceName(),TreeTypeEnum.CRAMERA.getTypeVal(),device.getDeviceType(),null,
                                    device.getLon(),device.getLat());
                            if(tree.getItems() == null){
                                tree.setItems(new ArrayList<>());
                            }
                            tree.getItems().add(deviceTree);
                        }
                    }
                }
            }
        }
    }
}
